home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / tests / syscalls / fork / forkTest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-31  |  5.9 KB  |  297 lines

  1. /* 
  2.  * forkTest.c --
  3.  *
  4.  *    Test the fork system call.
  5.  *
  6.  * Copyright 1990 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header$";
  18. #endif /* not lint */
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <errno.h>
  25. #include <sys/file.h>
  26. #include <sys/param.h>
  27. #include <sys/wait.h>
  28.  
  29. extern int errno;
  30. static int errors;
  31.  
  32. static int staticValue;
  33. static int parentPID;
  34.  
  35. #ifdef __STDC__
  36. static void testProcessLimits(void);
  37. static void testFileOperations(void);
  38. #else
  39. static void testProcessLimits();
  40. static void testFileOperations();
  41. #endif
  42.  
  43. /*
  44.  *----------------------------------------------------------------------
  45.  *
  46.  * main --
  47.  *
  48.  *    
  49.  *      
  50.  *
  51.  * Results:
  52.  *    Exits with a zero exit status if everything works properly,
  53.  *      non-zero otherwise.
  54.  *
  55.  * Side effects:
  56.  *    
  57.  *      
  58.  *
  59.  *----------------------------------------------------------------------
  60.  */
  61.  
  62. void
  63. main()
  64. {
  65.  
  66.  
  67.     parentPID = getpid();
  68.     if (parentPID == 0 || parentPID < 0) {
  69.     (void) fprintf(stderr, "Bad process id: %d\n", parentPID);
  70.     exit(EXIT_FAILURE);
  71.     }
  72.  
  73.     testFileOperations();
  74.  
  75.  
  76.     testProcessLimits();
  77.  
  78.  
  79. }
  80.  
  81.  
  82.  
  83.  
  84. /*
  85.  *----------------------------------------------------------------------
  86.  *
  87.  * testProcessLimit --
  88.  *
  89.  *
  90.  * Results:
  91.  *    none.
  92.  *
  93.  * Side effects:
  94.  *      Prints a message to stderr nad increments `errors' if there is
  95.  *      an error.
  96.  *
  97.  *----------------------------------------------------------------------
  98.  */
  99.  
  100. static void
  101. testProcessLimits()
  102. {
  103.     int localValue;
  104.     int *heapValuePtr;
  105.     int w;
  106.     union wait ws;
  107.  
  108.     while (staticValue < 10) {
  109.     ++staticValue;
  110.     localValue = staticValue;
  111.     if ((heapValuePtr = (int *) malloc(sizeof(int))) == NULL) {
  112.         (void) fprintf(stderr, "Malloc failed: %s\n", strerror(errno));
  113.         ++errors;
  114.         if (getpid() != parentPID) {
  115.         exit(EXIT_FAILURE);
  116.         }
  117.         return;
  118.     }
  119.     *heapValuePtr = staticValue;
  120.     switch (fork()) {
  121.  
  122.     case -1:
  123.         switch (errno) {
  124.  
  125.         case EAGAIN:
  126.         case ENOMEM:
  127.         break;
  128.  
  129.         default:
  130.         (void) fprintf(stderr, "Bad errno (%d): %s\n",
  131.             errno, strerror(errno));
  132.         ++errors;
  133.         break;
  134.         }
  135.         break;
  136.  
  137.     case 0:     /* child */
  138.         if (localValue != staticValue) {
  139.         (void) fprintf(stderr, "Child's local value is wrong.\n");
  140.         ++errors;
  141.         break;
  142.         }
  143.         if (*heapValuePtr != staticValue) {
  144.         (void) fprintf(stderr, "Child's heap value is wrong.\n");
  145.         ++errors;
  146.         break;
  147.         }
  148.         continue;
  149.  
  150.     default:    /* parent */
  151.         if (localValue != staticValue) {
  152.         (void) fprintf(stderr, "Parent's local value is wrong.\n");
  153.         ++errors;
  154.         break;
  155.         }
  156.         if (*heapValuePtr != staticValue) {
  157.         (void) fprintf(stderr, "Parent's heap value is wrong.\n");
  158.         ++errors;
  159.         break;
  160.         }
  161.         continue;
  162.     }
  163.     break;
  164.     }
  165.     while ((w = wait(&ws)) > 0) {
  166.     if (ws.w_retcode != EXIT_SUCCESS) {
  167.         ++errors;
  168.     }
  169.     }
  170.     if (getpid() != parentPID) {
  171.     exit((errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
  172.     }
  173.     return;
  174. }
  175.  
  176.  
  177.  
  178. /*
  179.  *----------------------------------------------------------------------
  180.  *
  181.  * testProcessLimit --
  182.  *
  183.  *      Make sure that the child inherits file descriptors properly.
  184.  *
  185.  * Results:
  186.  *    none.
  187.  *
  188.  * Side effects:
  189.  *      Prints a message to stderr nad increments `errors' if there is
  190.  *      an error.
  191.  *
  192.  *----------------------------------------------------------------------
  193.  */
  194.  
  195. static void
  196. testFileOperations()
  197. {
  198.     int fd;
  199.     static char tempfile[MAXPATHLEN];
  200.     char buffer[100];
  201.     int w;
  202.     union wait ws;
  203.  
  204.     if (tmpnam(tempfile) != tempfile) {
  205.     (void) fprintf(stderr, "tmpnam() returned incorrect value.\n");
  206.     ++errors;
  207.     return;
  208.     }
  209.     if ((fd = open(tempfile, O_RDWR|O_CREAT, 0666)) < 0) {
  210.     (void) fprintf(stderr, "Cannot create %s: %s\n",
  211.         tempfile, strerror(errno));
  212.     ++errors;
  213.     return;
  214.     }
  215.     if (write(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
  216.     (void) fprintf(stderr, "error writing to %s: %s\n",
  217.         tempfile, strerror(errno));
  218.     ++errors;
  219.     (void) unlink(tempfile);
  220.     return;
  221.     }
  222.     if (lseek(fd, 0L, L_INCR) != sizeof(buffer)) {
  223.     (void) fprintf(stderr, "lseek error: %s\n", strerror(errno));
  224.     ++errors;
  225.     (void) unlink(tempfile);
  226.     return;
  227.     }
  228.     switch (fork()) {
  229.  
  230.     case -1:
  231.     (void) fprintf(stderr, "fork failed: %s\n", strerror(errno));
  232.     ++errors;
  233.     (void) unlink(tempfile);
  234.     return;
  235.  
  236.     case 0:
  237.     if (lseek(fd, 0L, L_INCR) != sizeof(buffer)) {
  238.         (void) fprintf(stderr, "Child did not inherit file offset\n");
  239.         ++errors;
  240.     }
  241.     if (write(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
  242.         (void) fprintf(stderr, "error writing to %s: %s\n",
  243.         tempfile, strerror(errno));
  244.         ++errors;
  245.     }
  246.     exit(errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
  247.  
  248.     default:
  249.     while ((w = wait(&ws)) > 0) {
  250.         if (ws.w_retcode != EXIT_SUCCESS) {
  251.         (void) fprintf(stderr, "Child exited with non-zero status\n");
  252.         ++errors;
  253.         return;
  254.         }
  255.     }
  256.     break;
  257.     }
  258.     if (lseek(fd, 0L, L_INCR) != 2 * sizeof(buffer)) {
  259.     (void) fprintf(stderr, "Parents file offset is wrong\n");
  260.     ++errors;
  261.     (void) unlink(tempfile);
  262.     return;
  263.     }
  264.     switch (fork()) {
  265.  
  266.     case -1:
  267.     (void) fprintf(stderr, "fork failed: %s\n", strerror(errno));
  268.     ++errors;
  269.     (void) unlink(tempfile);
  270.     return;
  271.  
  272.     case 0:
  273.     if (close(fd)) {
  274.         (void) fprintf(stderr, "child close failed: %s\n", strerror(errno));
  275.         ++errors;
  276.     }
  277.     exit(errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
  278.  
  279.     default:
  280.     while ((w = wait(&ws)) > 0) {
  281.         if (ws.w_retcode != EXIT_SUCCESS) {
  282.         (void) fprintf(stderr, "Child exited with non-zero status\n");
  283.         ++errors;
  284.         return;
  285.         }
  286.     }
  287.     break;
  288.     }
  289.     if (close(fd)) {
  290.     (void) fprintf(stderr, "parent close failed: %s\n", strerror(errno));
  291.     ++errors;
  292.     }
  293.     (void) unlink(tempfile);
  294.     return;
  295. }
  296.  
  297.